Skip to content

fix: Add lower limits for mockserver#990

Open
azgabur wants to merge 1 commit into
Kuadrant:mainfrom
azgabur:mockserver-limits
Open

fix: Add lower limits for mockserver#990
azgabur wants to merge 1 commit into
Kuadrant:mainfrom
azgabur:mockserver-limits

Conversation

@azgabur
Copy link
Copy Markdown
Member

@azgabur azgabur commented May 29, 2026

Description

Lowered limits for mockserver deployment as 2G of memory was too generous for a deployment which will be deployed multiple times on a cluster. I had it cause cluster starvation when it requested about 100g of memory while running release pipeline. Normally mockserver uses about 200mb. I also added java parameter for JVM to prevent OOM.

Verification

make smoke

touches global code so requires 2 reviewers.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 29, 2026

Warning

Review limit reached

@azgabur, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 30 minutes and 51 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: cac7ce3b-740d-4641-a5e2-56ed75090589

📥 Commits

Reviewing files that changed from the base of the PR and between 066c0fc and d3dabad.

📒 Files selected for processing (1)
  • testsuite/backend/mockserver.py
📝 Walkthrough

Walkthrough

The MockServer backend deployment configuration is updated to provide consistent resource limits and environment defaults. A default env_limit dictionary containing JVM heap options is defined and merged with any configuration-provided environment variables, ensuring consistent Java memory settings. Container resources are specified with explicit CPU and memory limits alongside a memory request.

Changes

MockServer deployment resource and environment configuration

Layer / File(s) Summary
MockServer deployment resource and environment defaults
testsuite/backend/mockserver.py
Adds a default env_limit dict containing JAVA_TOOL_OPTIONS: -Xmx300m and updates the container spec to define explicit CPU (100m) and memory (300Mi limit, 200Mi request) resources. Environment variables are now merged from both defaults and configuration, ensuring the Java heap option is always present regardless of whether a config is supplied.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Poem

🐰 A MockServer springs to life with proper bounds,
With heap limits set and resources sound,
Default env vars dance with config's grace,
Kubernetes deployment finds its place!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'fix: Add lower limits for mockserver' directly aligns with the main change: reducing resource limits for the mockserver deployment to prevent cluster starvation.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The pull request description includes the required Description, Changes (implicit in description), and Verification sections, though changes could be more explicit.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@azgabur
Copy link
Copy Markdown
Member Author

azgabur commented May 29, 2026

/make smoke

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 29, 2026

Test run completed (make smoke) and can be found here

Short Test Summary
=========================== short test summary info ============================
FAILED testsuite/tests/singlecluster/authorino/identity/api_key/test_auth_credentials.py::test_custom_selector[authorizationHeader] - assert 500 == 200
 +  where 500 = <testsuite.httpx.Result object at 0x7fa1e81f71d0>.status_code
FAILED testsuite/tests/singlecluster/gateway/test_basic.py::test_gateway_basic_dns_tls - assert 500 == 200
 +  where 500 = <testsuite.httpx.Result object at 0x7f5d17346e70>.status_code
FAILED testsuite/tests/singlecluster/limitador/test_basic_limit.py::test_limit[2 requests every 15 sec-route] - AssertionError: Status code assertion failed for request 1 out of 2 requests: Result[status_code=500] != 200
FAILED testsuite/tests/singlecluster/limitador/test_basic_limit.py::test_limit[2 requests every 15 sec-gateway] - AssertionError: assert 200 == 429
 +  where 200 = <testsuite.httpx.Result object at 0x7fe759d224e0>.status_code
 +    where <testsuite.httpx.Result object at 0x7fe759d224e0> = get('/get')
 +      where get = <testsuite.httpx.ForceSNIClient object at 0x7fe76035b1d0>.get
============== 4 failed, 1 passed, 12 rerun in 211.71s (0:03:31) ===============
Full Output
poetry lock
Creating virtualenv kuadrant-testsuite-6EPd9kcO-py3.12 in /home/runner/.cache/pypoetry/virtualenvs
Updating dependencies
Resolving dependencies...

Writing lock file
Installing dependencies from lock file

Package operations: 55 installs, 0 updates, 0 removals

  - Installing aiofiles (25.1.0)
  - Installing anyio (4.13.0)
  - Installing apyproxy (0.2.2)
  - Installing backoff (2.2.1)
  - Installing build (1.5.0)
  - Installing certifi (2026.5.20)
  - Installing cffi (2.0.0)
  - Installing charset-normalizer (3.4.7)
  - Installing cryptography (48.0.0)
  - Installing deprecation (2.1.0)
  - Installing dnspython (2.8.0)
  - Installing dynaconf (3.2.13)
  - Installing execnet (2.1.2)
  - Installing greenlet (3.5.1)
  - Installing grpcio (1.80.0)
  - Installing h11 (0.16.0)
  - Installing h2 (4.3.0)
  - Installing hpack (4.1.0)
  - Installing httpcore (1.0.9)
  - Installing httpx (0.28.1)
  - Installing hvac (2.4.0)
  - Installing hyperframe (6.1.0)
  - Installing idna (3.17)
  - Installing iniconfig (2.3.0)
  - Installing jinja2 (3.1.6)
  - Installing jwcrypto (1.5.7)
  - Installing lxml (6.1.1)
  - Installing markupsafe (3.0.3)
  - Installing openshift-client (2.0.5)
  - Installing packaging (26.2)
  - Installing playwright (1.57.0)
  - Installing pluggy (1.6.0)
  - Installing protobuf (6.33.6)
  - Installing pycparser (3.0)
  - Installing pyee (13.0.1)
  - Installing pygments (2.20.0)
  - Installing pyjwt (2.13.0)
  - Installing pyproject-hooks (1.2.0)
  - Installing pytest (9.0.3)
  - Installing pytest-base-url (2.1.0)
  - Installing pytest-html (4.2.0)
  - Installing pytest-metadata (3.1.1)
  - Installing pytest-playwright (0.8.0)
  - Installing pytest-rerunfailures (16.3)
  - Installing pytest-xdist (3.8.0)
  - Installing python-keycloak (7.1.1)
  - Installing python-slugify (8.0.4)
  - Installing pyyaml (6.0.3)
  - Installing requests (2.34.2)
  - Installing requests-toolbelt (1.0.0)
  - Installing six (1.17.0)
  - Installing text-unidecode (1.3)
  - Installing typing-extensions (4.15.0)
  - Installing urllib3 (2.7.0)
  - Installing weakget (1.0)
poetry run python -m pytest --tb=short --reruns 3 --reruns-delay 2 -o cache_dir=./.pytest_cache.smoke -n4 -m 'smoke' --dist loadfile --enforce -vv testsuite/tests/
============================= test session starts ==============================
platform linux -- Python 3.12.3, pytest-9.0.3, pluggy-1.6.0 -- /home/runner/.cache/pypoetry/virtualenvs/kuadrant-testsuite-6EPd9kcO-py3.12/bin/python
cachedir: .pytest_cache.smoke
metadata: {'Python': '3.12.3', 'Platform': 'Linux-6.17.0-1015-azure-x86_64-with-glibc2.39', 'Packages': {'pytest': '9.0.3', 'pluggy': '1.6.0'}, 'Plugins': {'base-url': '2.1.0', 'html': '4.2.0', 'playwright': '0.8.0', 'anyio': '4.13.0', 'rerunfailures': '16.3', 'metadata': '3.1.1', 'xdist': '3.8.0'}, 'CI': 'true', 'JAVA_HOME': '/usr/lib/jvm/temurin-17-jdk-amd64', 'Base URL': '', 'Kuadrant': []}

rootdir: /home/runner/work/testsuite/testsuite
configfile: pyproject.toml
plugins: base-url-2.1.0, html-4.2.0, playwright-0.8.0, anyio-4.13.0, rerunfailures-16.3, metadata-3.1.1, xdist-3.8.0
created: 4/4 workers
4 workers [5 items]

scheduling tests via LoadFileScheduling

testsuite/tests/singlecluster/limitador/test_basic_limit.py::test_limit[2 requests every 15 sec-route] 
testsuite/tests/singlecluster/gateway/test_basic.py::test_gateway_readiness 
testsuite/tests/singlecluster/authorino/identity/api_key/test_auth_credentials.py::test_custom_selector[authorizationHeader] 
[gw0] [ 20%] PASSED testsuite/tests/singlecluster/gateway/test_basic.py::test_gateway_readiness 
testsuite/tests/singlecluster/gateway/test_basic.py::test_gateway_basic_dns_tls 
[gw0] [ 40%] RERUN testsuite/tests/singlecluster/gateway/test_basic.py::test_gateway_basic_dns_tls 
testsuite/tests/singlecluster/gateway/test_basic.py::test_gateway_basic_dns_tls 
[gw1] [ 60%] RERUN testsuite/tests/singlecluster/authorino/identity/api_key/test_auth_credentials.py::test_custom_selector[authorizationHeader] 
testsuite/tests/singlecluster/authorino/identity/api_key/test_auth_credentials.py::test_custom_selector[authorizationHeader] 
[gw0] [ 60%] RERUN testsuite/tests/singlecluster/gateway/test_basic.py::test_gateway_basic_dns_tls 
testsuite/tests/singlecluster/gateway/test_basic.py::test_gateway_basic_dns_tls 
[gw1] [ 60%] RERUN testsuite/tests/singlecluster/authorino/identity/api_key/test_auth_credentials.py::test_custom_selector[authorizationHeader] 
testsuite/tests/singlecluster/authorino/identity/api_key/test_auth_credentials.py::test_custom_selector[authorizationHeader] 
[gw0] [ 60%] RERUN testsuite/tests/singlecluster/gateway/test_basic.py::test_gateway_basic_dns_tls 
testsuite/tests/singlecluster/gateway/test_basic.py::test_gateway_basic_dns_tls 
[gw1] [ 60%] RERUN testsuite/tests/singlecluster/authorino/identity/api_key/test_auth_credentials.py::test_custom_selector[authorizationHeader] 
testsuite/tests/singlecluster/authorino/identity/api_key/test_auth_credentials.py::test_custom_selector[authorizationHeader] 
[gw1] [ 60%] FAILED testsuite/tests/singlecluster/authorino/identity/api_key/test_auth_credentials.py::test_custom_selector[authorizationHeader] 
[gw0] [ 60%] FAILED testsuite/tests/singlecluster/gateway/test_basic.py::test_gateway_basic_dns_tls 
[gw2] [ 80%] RERUN testsuite/tests/singlecluster/limitador/test_basic_limit.py::test_limit[2 requests every 15 sec-route] 
testsuite/tests/singlecluster/limitador/test_basic_limit.py::test_limit[2 requests every 15 sec-route] 
[gw2] [ 80%] RERUN testsuite/tests/singlecluster/limitador/test_basic_limit.py::test_limit[2 requests every 15 sec-route] 
testsuite/tests/singlecluster/limitador/test_basic_limit.py::test_limit[2 requests every 15 sec-route] 
[gw2] [ 80%] RERUN testsuite/tests/singlecluster/limitador/test_basic_limit.py::test_limit[2 requests every 15 sec-route] 
testsuite/tests/singlecluster/limitador/test_basic_limit.py::test_limit[2 requests every 15 sec-route] 
[gw2] [ 80%] FAILED testsuite/tests/singlecluster/limitador/test_basic_limit.py::test_limit[2 requests every 15 sec-route] 
testsuite/tests/singlecluster/limitador/test_basic_limit.py::test_limit[2 requests every 15 sec-gateway] 
[gw2] [100%] RERUN testsuite/tests/singlecluster/limitador/test_basic_limit.py::test_limit[2 requests every 15 sec-gateway] 
testsuite/tests/singlecluster/limitador/test_basic_limit.py::test_limit[2 requests every 15 sec-gateway] 
[gw2] [100%] RERUN testsuite/tests/singlecluster/limitador/test_basic_limit.py::test_limit[2 requests every 15 sec-gateway] 
testsuite/tests/singlecluster/limitador/test_basic_limit.py::test_limit[2 requests every 15 sec-gateway] 
[gw2] [100%] RERUN testsuite/tests/singlecluster/limitador/test_basic_limit.py::test_limit[2 requests every 15 sec-gateway] 
testsuite/tests/singlecluster/limitador/test_basic_limit.py::test_limit[2 requests every 15 sec-gateway] 
[gw2] [100%] FAILED testsuite/tests/singlecluster/limitador/test_basic_limit.py::test_limit[2 requests every 15 sec-gateway] 

=================================== FAILURES ===================================
__________________ test_custom_selector[authorizationHeader] ___________________
[gw1] linux -- Python 3.12.3 /home/runner/.cache/pypoetry/virtualenvs/kuadrant-testsuite-6EPd9kcO-py3.12/bin/python
testsuite/tests/singlecluster/authorino/identity/api_key/test_auth_credentials.py:34: in test_custom_selector
    assert response.status_code == 200
E   assert 500 == 200
E    +  where 500 = <testsuite.httpx.Result object at 0x7fa1e81f71d0>.status_code
------------------------------ Captured log call -------------------------------
09:24:17 +0000 INFO:backoff:Backing off request(...) for 1.0s (Result[error=timed out])
09:24:18 +0000 INFO:httpx:HTTP Request: GET http://172.18.255.208/get "HTTP/1.1 500 Internal Server Error"
------------------------------ Captured log call -------------------------------
09:24:20 +0000 INFO:httpx:HTTP Request: GET http://172.18.255.208/get "HTTP/1.1 500 Internal Server Error"
------------------------------ Captured log call -------------------------------
09:24:22 +0000 INFO:httpx:HTTP Request: GET http://172.18.255.208/get "HTTP/1.1 500 Internal Server Error"
------------------------------ Captured log call -------------------------------
09:24:24 +0000 INFO:httpx:HTTP Request: GET http://172.18.255.208/get "HTTP/1.1 500 Internal Server Error"
__________________________ test_gateway_basic_dns_tls __________________________
[gw0] linux -- Python 3.12.3 /home/runner/.cache/pypoetry/virtualenvs/kuadrant-testsuite-6EPd9kcO-py3.12/bin/python
testsuite/tests/singlecluster/gateway/test_basic.py:24: in test_gateway_basic_dns_tls
    assert result.status_code == 200
E   assert 500 == 200
E    +  where 500 = <testsuite.httpx.Result object at 0x7f5d17346e70>.status_code
------------------------------ Captured log call -------------------------------
09:24:16 +0000 INFO:backoff:Backing off request(...) for 1.0s (Result[error=[Errno -5] No address associated with hostname])
09:24:18 +0000 INFO:httpx:HTTP Request: GET https://hostname-runner--gvfu.t6uj4ze.aws.kuadrant-qe.hcpapps.net/get "HTTP/1.1 500 Internal Server Error"
------------------------------ Captured log call -------------------------------
09:24:20 +0000 INFO:httpx:HTTP Request: GET https://hostname-runner--gvfu.t6uj4ze.aws.kuadrant-qe.hcpapps.net/get "HTTP/1.1 500 Internal Server Error"
------------------------------ Captured log call -------------------------------
09:24:22 +0000 INFO:httpx:HTTP Request: GET https://hostname-runner--gvfu.t6uj4ze.aws.kuadrant-qe.hcpapps.net/get "HTTP/1.1 500 Internal Server Error"
------------------------------ Captured log call -------------------------------
09:24:24 +0000 INFO:httpx:HTTP Request: GET https://hostname-runner--gvfu.t6uj4ze.aws.kuadrant-qe.hcpapps.net/get "HTTP/1.1 500 Internal Server Error"
---------------------------- Captured log teardown -----------------------------
09:24:24 +0000 INFO:backoff:Backing off _wait_dnsrecord_deleted(...) for 0.1s ([<testsuite.kuadrant.policy.dns.DNSRecord object at 0x7f5d17142c30>])
09:24:24 +0000 INFO:backoff:Backing off _wait_dnsrecord_deleted(...) for 0.9s ([<testsuite.kuadrant.policy.dns.DNSRecord object at 0x7f5d15ad6e10>])
09:24:25 +0000 INFO:backoff:Backing off _wait_dnsrecord_deleted(...) for 0.8s ([<testsuite.kuadrant.policy.dns.DNSRecord object at 0x7f5d15af9a30>])
09:24:26 +0000 INFO:backoff:Backing off _wait_dnsrecord_deleted(...) for 1.0s ([<testsuite.kuadrant.policy.dns.DNSRecord object at 0x7f5d15af9fd0>])
09:24:27 +0000 INFO:backoff:Backing off _wait_dnsrecord_deleted(...) for 2.6s ([<testsuite.kuadrant.policy.dns.DNSRecord object at 0x7f5d15afa420>])
__________________ test_limit[2 requests every 15 sec-route] ___________________
[gw2] linux -- Python 3.12.3 /home/runner/.cache/pypoetry/virtualenvs/kuadrant-testsuite-6EPd9kcO-py3.12/bin/python
testsuite/tests/singlecluster/limitador/test_basic_limit.py:37: in test_limit
    responses.assert_all(status_code=200)
testsuite/httpx/__init__.py:108: in assert_all
    assert request.status_code == status_code, (
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
E   AssertionError: Status code assertion failed for request 1 out of 2 requests: Result[status_code=500] != 200
------------------------------ Captured log call -------------------------------
09:24:12 +0000 INFO:httpx:HTTP Request: GET http://172.18.255.209/get "HTTP/1.1 500 Internal Server Error"
09:24:12 +0000 INFO:httpx:HTTP Request: GET http://172.18.255.209/get "HTTP/1.1 500 Internal Server Error"
------------------------------ Captured log call -------------------------------
09:24:32 +0000 INFO:httpx:HTTP Request: GET http://172.18.255.209/get "HTTP/1.1 500 Internal Server Error"
09:24:32 +0000 INFO:httpx:HTTP Request: GET http://172.18.255.209/get "HTTP/1.1 500 Internal Server Error"
------------------------------ Captured log call -------------------------------
09:24:52 +0000 INFO:httpx:HTTP Request: GET http://172.18.255.209/get "HTTP/1.1 500 Internal Server Error"
09:24:52 +0000 INFO:httpx:HTTP Request: GET http://172.18.255.209/get "HTTP/1.1 500 Internal Server Error"
------------------------------ Captured log call -------------------------------
09:25:12 +0000 INFO:httpx:HTTP Request: GET http://172.18.255.209/get "HTTP/1.1 500 Internal Server Error"
09:25:12 +0000 INFO:httpx:HTTP Request: GET http://172.18.255.209/get "HTTP/1.1 500 Internal Server Error"
_________________ test_limit[2 requests every 15 sec-gateway] __________________
[gw2] linux -- Python 3.12.3 /home/runner/.cache/pypoetry/virtualenvs/kuadrant-testsuite-6EPd9kcO-py3.12/bin/python
testsuite/tests/singlecluster/limitador/test_basic_limit.py:38: in test_limit
    assert client.get("/get").status_code == 429
E   AssertionError: assert 200 == 429
E    +  where 200 = <testsuite.httpx.Result object at 0x7fe759d224e0>.status_code
E    +    where <testsuite.httpx.Result object at 0x7fe759d224e0> = get('/get')
E    +      where get = <testsuite.httpx.ForceSNIClient object at 0x7fe76035b1d0>.get
------------------------------ Captured log call -------------------------------
09:25:23 +0000 INFO:backoff:Backing off request(...) for 1.0s (Result[error=timed out])
09:25:29 +0000 INFO:backoff:Backing off request(...) for 1.0s (Result[error=timed out])
09:25:35 +0000 INFO:backoff:Backing off request(...) for 2.0s (Result[error=timed out])
09:25:42 +0000 INFO:backoff:Backing off request(...) for 3.0s (Result[error=timed out])
09:25:46 +0000 INFO:httpx:HTTP Request: GET http://172.18.255.209/get "HTTP/1.1 200 OK"
09:25:46 +0000 INFO:httpx:HTTP Request: GET http://172.18.255.209/get "HTTP/1.1 200 OK"
09:25:46 +0000 INFO:httpx:HTTP Request: GET http://172.18.255.209/get "HTTP/1.1 200 OK"
------------------------------ Captured log call -------------------------------
09:26:07 +0000 INFO:httpx:HTTP Request: GET http://172.18.255.209/get "HTTP/1.1 200 OK"
09:26:07 +0000 INFO:httpx:HTTP Request: GET http://172.18.255.209/get "HTTP/1.1 200 OK"
09:26:08 +0000 INFO:httpx:HTTP Request: GET http://172.18.255.209/get "HTTP/1.1 200 OK"
------------------------------ Captured log call -------------------------------
09:26:28 +0000 INFO:httpx:HTTP Request: GET http://172.18.255.209/get "HTTP/1.1 200 OK"
09:26:29 +0000 INFO:httpx:HTTP Request: GET http://172.18.255.209/get "HTTP/1.1 200 OK"
09:26:30 +0000 INFO:httpx:HTTP Request: GET http://172.18.255.209/get "HTTP/1.1 200 OK"
------------------------------ Captured log call -------------------------------
09:26:50 +0000 INFO:httpx:HTTP Request: GET http://172.18.255.209/get "HTTP/1.1 200 OK"
09:26:51 +0000 INFO:httpx:HTTP Request: GET http://172.18.255.209/get "HTTP/1.1 200 OK"
09:26:51 +0000 INFO:httpx:HTTP Request: GET http://172.18.255.209/get "HTTP/1.1 200 OK"
=========================== short test summary info ============================
FAILED testsuite/tests/singlecluster/authorino/identity/api_key/test_auth_credentials.py::test_custom_selector[authorizationHeader] - assert 500 == 200
 +  where 500 = <testsuite.httpx.Result object at 0x7fa1e81f71d0>.status_code
FAILED testsuite/tests/singlecluster/gateway/test_basic.py::test_gateway_basic_dns_tls - assert 500 == 200
 +  where 500 = <testsuite.httpx.Result object at 0x7f5d17346e70>.status_code
FAILED testsuite/tests/singlecluster/limitador/test_basic_limit.py::test_limit[2 requests every 15 sec-route] - AssertionError: Status code assertion failed for request 1 out of 2 requests: Result[status_code=500] != 200
FAILED testsuite/tests/singlecluster/limitador/test_basic_limit.py::test_limit[2 requests every 15 sec-gateway] - AssertionError: assert 200 == 429
 +  where 200 = <testsuite.httpx.Result object at 0x7fe759d224e0>.status_code
 +    where <testsuite.httpx.Result object at 0x7fe759d224e0> = get('/get')
 +      where get = <testsuite.httpx.ForceSNIClient object at 0x7fe76035b1d0>.get
============== 4 failed, 1 passed, 12 rerun in 211.71s (0:03:31) ===============
make: *** [Makefile:36: smoke] Error 1

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
testsuite/backend/mockserver.py (1)

82-82: ⚡ Quick win

Add CPU request for predictable scheduling.

The container specifies a CPU limit but no CPU request. Setting a CPU request improves the quality-of-service class and ensures more predictable scheduling behaviour.

♻️ Suggested improvement
-            resources=ContainerResources(limits_cpu="100m", limits_memory="300Mi", requests_memory="200Mi"),
+            resources=ContainerResources(limits_cpu="100m", limits_memory="300Mi", requests_cpu="100m", requests_memory="200Mi"),
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@testsuite/backend/mockserver.py` at line 82, The ContainerResources
instantiation sets limits_cpu but lacks a CPU request, which can cause
unpredictable scheduling; update the call to ContainerResources (the constructor
used at the resource variable) to include a CPU request (e.g., requests_cpu set
to an appropriate value such as "100m" or a value matching your expected
baseline) along with existing limits_cpu/limits_memory/requests_memory so the
container has both CPU limit and CPU request for predictable scheduling and
improved QoS.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@testsuite/backend/mockserver.py`:
- Line 73: In MockserverBackend.commit, reduce the JVM heap so it leaves
headroom by changing env_limit = {"JAVA_TOOL_OPTIONS": "-Xmx300m"} to a smaller
heap (e.g. "-Xmx200m" or similar), and add a CPU request alongside the existing
limits (update ContainerResources(...) to include requests_cpu="50m" or an
appropriate value while keeping limits_cpu="100m"); ensure the env merge (env =
env_limit | self.config.env if self.config else env_limit) still applies default
JAVA_TOOL_OPTIONS but adjust defaults as above so the container
limits_memory="300Mi" has sufficient non-heap headroom.

---

Nitpick comments:
In `@testsuite/backend/mockserver.py`:
- Line 82: The ContainerResources instantiation sets limits_cpu but lacks a CPU
request, which can cause unpredictable scheduling; update the call to
ContainerResources (the constructor used at the resource variable) to include a
CPU request (e.g., requests_cpu set to an appropriate value such as "100m" or a
value matching your expected baseline) along with existing
limits_cpu/limits_memory/requests_memory so the container has both CPU limit and
CPU request for predictable scheduling and improved QoS.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2482a12d-bd9b-4602-a537-dcd55adb7e54

📥 Commits

Reviewing files that changed from the base of the PR and between 85a3fb6 and 066c0fc.

📒 Files selected for processing (1)
  • testsuite/backend/mockserver.py

Comment thread testsuite/backend/mockserver.py Outdated
@azgabur azgabur force-pushed the mockserver-limits branch from 066c0fc to 676dfbc Compare May 29, 2026 09:46
Signed-off-by: Alex Zgabur <azgabur@redhat.com>
@azgabur azgabur force-pushed the mockserver-limits branch from 676dfbc to d3dabad Compare May 29, 2026 09:47
@azgabur
Copy link
Copy Markdown
Member Author

azgabur commented May 29, 2026

/make smoke

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 29, 2026

Test run completed (make smoke) and can be found here

Short Test Summary
=========================== short test summary info ============================
FAILED testsuite/tests/singlecluster/authorino/identity/api_key/test_auth_credentials.py::test_custom_selector[authorizationHeader] - assert 500 == 200
 +  where 500 = <testsuite.httpx.Result object at 0x7fef10902270>.status_code
FAILED testsuite/tests/singlecluster/gateway/test_basic.py::test_gateway_basic_dns_tls - assert 500 == 200
 +  where 500 = <testsuite.httpx.Result object at 0x7f71a9096b70>.status_code
FAILED testsuite/tests/singlecluster/limitador/test_basic_limit.py::test_limit[2 requests every 15 sec-route] - AssertionError: Status code assertion failed for request 1 out of 2 requests: Result[status_code=500] != 200
FAILED testsuite/tests/singlecluster/limitador/test_basic_limit.py::test_limit[2 requests every 15 sec-gateway] - AssertionError: assert 200 == 429
 +  where 200 = <testsuite.httpx.Result object at 0x7fca8fbf7f20>.status_code
 +    where <testsuite.httpx.Result object at 0x7fca8fbf7f20> = get('/get')
 +      where get = <testsuite.httpx.ForceSNIClient object at 0x7fca8ff85d00>.get
============== 4 failed, 1 passed, 12 rerun in 222.67s (0:03:42) ===============
Full Output
poetry lock
Creating virtualenv kuadrant-testsuite-6EPd9kcO-py3.12 in /home/runner/.cache/pypoetry/virtualenvs
Updating dependencies
Resolving dependencies...

Writing lock file
Installing dependencies from lock file

Package operations: 55 installs, 0 updates, 0 removals

  - Installing aiofiles (25.1.0)
  - Installing anyio (4.13.0)
  - Installing apyproxy (0.2.2)
  - Installing backoff (2.2.1)
  - Installing build (1.5.0)
  - Installing certifi (2026.5.20)
  - Installing cffi (2.0.0)
  - Installing charset-normalizer (3.4.7)
  - Installing cryptography (48.0.0)
  - Installing deprecation (2.1.0)
  - Installing dnspython (2.8.0)
  - Installing dynaconf (3.2.13)
  - Installing execnet (2.1.2)
  - Installing greenlet (3.5.1)
  - Installing grpcio (1.80.0)
  - Installing h11 (0.16.0)
  - Installing h2 (4.3.0)
  - Installing hpack (4.1.0)
  - Installing httpcore (1.0.9)
  - Installing httpx (0.28.1)
  - Installing hvac (2.4.0)
  - Installing hyperframe (6.1.0)
  - Installing idna (3.17)
  - Installing iniconfig (2.3.0)
  - Installing jinja2 (3.1.6)
  - Installing jwcrypto (1.5.7)
  - Installing lxml (6.1.1)
  - Installing markupsafe (3.0.3)
  - Installing openshift-client (2.0.5)
  - Installing packaging (26.2)
  - Installing playwright (1.57.0)
  - Installing pluggy (1.6.0)
  - Installing protobuf (6.33.6)
  - Installing pycparser (3.0)
  - Installing pyee (13.0.1)
  - Installing pygments (2.20.0)
  - Installing pyjwt (2.13.0)
  - Installing pyproject-hooks (1.2.0)
  - Installing pytest (9.0.3)
  - Installing pytest-base-url (2.1.0)
  - Installing pytest-html (4.2.0)
  - Installing pytest-metadata (3.1.1)
  - Installing pytest-playwright (0.8.0)
  - Installing pytest-rerunfailures (16.3)
  - Installing pytest-xdist (3.8.0)
  - Installing python-keycloak (7.1.1)
  - Installing python-slugify (8.0.4)
  - Installing pyyaml (6.0.3)
  - Installing requests (2.34.2)
  - Installing requests-toolbelt (1.0.0)
  - Installing six (1.17.0)
  - Installing text-unidecode (1.3)
  - Installing typing-extensions (4.15.0)
  - Installing urllib3 (2.7.0)
  - Installing weakget (1.0)
poetry run python -m pytest --tb=short --reruns 3 --reruns-delay 2 -o cache_dir=./.pytest_cache.smoke -n4 -m 'smoke' --dist loadfile --enforce -vv testsuite/tests/
============================= test session starts ==============================
platform linux -- Python 3.12.3, pytest-9.0.3, pluggy-1.6.0 -- /home/runner/.cache/pypoetry/virtualenvs/kuadrant-testsuite-6EPd9kcO-py3.12/bin/python
cachedir: .pytest_cache.smoke
metadata: {'Python': '3.12.3', 'Platform': 'Linux-6.17.0-1015-azure-x86_64-with-glibc2.39', 'Packages': {'pytest': '9.0.3', 'pluggy': '1.6.0'}, 'Plugins': {'base-url': '2.1.0', 'html': '4.2.0', 'playwright': '0.8.0', 'anyio': '4.13.0', 'rerunfailures': '16.3', 'metadata': '3.1.1', 'xdist': '3.8.0'}, 'CI': 'true', 'JAVA_HOME': '/usr/lib/jvm/temurin-17-jdk-amd64', 'Base URL': '', 'Kuadrant': []}

rootdir: /home/runner/work/testsuite/testsuite
configfile: pyproject.toml
plugins: base-url-2.1.0, html-4.2.0, playwright-0.8.0, anyio-4.13.0, rerunfailures-16.3, metadata-3.1.1, xdist-3.8.0
created: 4/4 workers
4 workers [5 items]

scheduling tests via LoadFileScheduling

testsuite/tests/singlecluster/gateway/test_basic.py::test_gateway_readiness 
testsuite/tests/singlecluster/authorino/identity/api_key/test_auth_credentials.py::test_custom_selector[authorizationHeader] 
testsuite/tests/singlecluster/limitador/test_basic_limit.py::test_limit[2 requests every 15 sec-route] 
[gw3] [ 20%] RERUN testsuite/tests/singlecluster/authorino/identity/api_key/test_auth_credentials.py::test_custom_selector[authorizationHeader] 
testsuite/tests/singlecluster/authorino/identity/api_key/test_auth_credentials.py::test_custom_selector[authorizationHeader] 
[gw3] [ 20%] RERUN testsuite/tests/singlecluster/authorino/identity/api_key/test_auth_credentials.py::test_custom_selector[authorizationHeader] 
testsuite/tests/singlecluster/authorino/identity/api_key/test_auth_credentials.py::test_custom_selector[authorizationHeader] 
[gw0] [ 40%] PASSED testsuite/tests/singlecluster/gateway/test_basic.py::test_gateway_readiness 
testsuite/tests/singlecluster/gateway/test_basic.py::test_gateway_basic_dns_tls 
[gw3] [ 40%] RERUN testsuite/tests/singlecluster/authorino/identity/api_key/test_auth_credentials.py::test_custom_selector[authorizationHeader] 
testsuite/tests/singlecluster/authorino/identity/api_key/test_auth_credentials.py::test_custom_selector[authorizationHeader] 
[gw3] [ 40%] FAILED testsuite/tests/singlecluster/authorino/identity/api_key/test_auth_credentials.py::test_custom_selector[authorizationHeader] 
[gw0] [ 60%] RERUN testsuite/tests/singlecluster/gateway/test_basic.py::test_gateway_basic_dns_tls 
testsuite/tests/singlecluster/gateway/test_basic.py::test_gateway_basic_dns_tls 
[gw0] [ 60%] RERUN testsuite/tests/singlecluster/gateway/test_basic.py::test_gateway_basic_dns_tls 
testsuite/tests/singlecluster/gateway/test_basic.py::test_gateway_basic_dns_tls 
[gw0] [ 60%] RERUN testsuite/tests/singlecluster/gateway/test_basic.py::test_gateway_basic_dns_tls 
testsuite/tests/singlecluster/gateway/test_basic.py::test_gateway_basic_dns_tls 
[gw1] [ 80%] RERUN testsuite/tests/singlecluster/limitador/test_basic_limit.py::test_limit[2 requests every 15 sec-route] 
testsuite/tests/singlecluster/limitador/test_basic_limit.py::test_limit[2 requests every 15 sec-route] 
[gw0] [ 80%] FAILED testsuite/tests/singlecluster/gateway/test_basic.py::test_gateway_basic_dns_tls 
[gw1] [ 80%] RERUN testsuite/tests/singlecluster/limitador/test_basic_limit.py::test_limit[2 requests every 15 sec-route] 
testsuite/tests/singlecluster/limitador/test_basic_limit.py::test_limit[2 requests every 15 sec-route] 
[gw1] [ 80%] RERUN testsuite/tests/singlecluster/limitador/test_basic_limit.py::test_limit[2 requests every 15 sec-route] 
testsuite/tests/singlecluster/limitador/test_basic_limit.py::test_limit[2 requests every 15 sec-route] 
[gw1] [ 80%] FAILED testsuite/tests/singlecluster/limitador/test_basic_limit.py::test_limit[2 requests every 15 sec-route] 
testsuite/tests/singlecluster/limitador/test_basic_limit.py::test_limit[2 requests every 15 sec-gateway] 
[gw1] [100%] RERUN testsuite/tests/singlecluster/limitador/test_basic_limit.py::test_limit[2 requests every 15 sec-gateway] 
testsuite/tests/singlecluster/limitador/test_basic_limit.py::test_limit[2 requests every 15 sec-gateway] 
[gw1] [100%] RERUN testsuite/tests/singlecluster/limitador/test_basic_limit.py::test_limit[2 requests every 15 sec-gateway] 
testsuite/tests/singlecluster/limitador/test_basic_limit.py::test_limit[2 requests every 15 sec-gateway] 
[gw1] [100%] RERUN testsuite/tests/singlecluster/limitador/test_basic_limit.py::test_limit[2 requests every 15 sec-gateway] 
testsuite/tests/singlecluster/limitador/test_basic_limit.py::test_limit[2 requests every 15 sec-gateway] 
[gw1] [100%] FAILED testsuite/tests/singlecluster/limitador/test_basic_limit.py::test_limit[2 requests every 15 sec-gateway] 

=================================== FAILURES ===================================
__________________ test_custom_selector[authorizationHeader] ___________________
[gw3] linux -- Python 3.12.3 /home/runner/.cache/pypoetry/virtualenvs/kuadrant-testsuite-6EPd9kcO-py3.12/bin/python
testsuite/tests/singlecluster/authorino/identity/api_key/test_auth_credentials.py:34: in test_custom_selector
    assert response.status_code == 200
E   assert 500 == 200
E    +  where 500 = <testsuite.httpx.Result object at 0x7fef10902270>.status_code
------------------------------ Captured log call -------------------------------
09:53:28 +0000 INFO:backoff:Backing off request(...) for 1.0s (Result[error=timed out])
09:53:29 +0000 INFO:httpx:HTTP Request: GET http://172.18.255.208/get "HTTP/1.1 500 Internal Server Error"
------------------------------ Captured log call -------------------------------
09:53:31 +0000 INFO:httpx:HTTP Request: GET http://172.18.255.208/get "HTTP/1.1 500 Internal Server Error"
------------------------------ Captured log call -------------------------------
09:53:33 +0000 INFO:httpx:HTTP Request: GET http://172.18.255.208/get "HTTP/1.1 500 Internal Server Error"
------------------------------ Captured log call -------------------------------
09:53:35 +0000 INFO:httpx:HTTP Request: GET http://172.18.255.208/get "HTTP/1.1 500 Internal Server Error"
__________________________ test_gateway_basic_dns_tls __________________________
[gw0] linux -- Python 3.12.3 /home/runner/.cache/pypoetry/virtualenvs/kuadrant-testsuite-6EPd9kcO-py3.12/bin/python
testsuite/tests/singlecluster/gateway/test_basic.py:24: in test_gateway_basic_dns_tls
    assert result.status_code == 200
E   assert 500 == 200
E    +  where 500 = <testsuite.httpx.Result object at 0x7f71a9096b70>.status_code
------------------------------ Captured log call -------------------------------
09:53:39 +0000 INFO:backoff:Backing off request(...) for 1.0s (Result[error=The read operation timed out])
09:53:40 +0000 INFO:httpx:HTTP Request: GET https://hostname-runner--te0b.ekzkbwk.aws.kuadrant-qe.hcpapps.net/get "HTTP/1.1 500 Internal Server Error"
------------------------------ Captured log call -------------------------------
09:53:42 +0000 INFO:httpx:HTTP Request: GET https://hostname-runner--te0b.ekzkbwk.aws.kuadrant-qe.hcpapps.net/get "HTTP/1.1 500 Internal Server Error"
------------------------------ Captured log call -------------------------------
09:53:44 +0000 INFO:httpx:HTTP Request: GET https://hostname-runner--te0b.ekzkbwk.aws.kuadrant-qe.hcpapps.net/get "HTTP/1.1 500 Internal Server Error"
------------------------------ Captured log call -------------------------------
09:53:46 +0000 INFO:httpx:HTTP Request: GET https://hostname-runner--te0b.ekzkbwk.aws.kuadrant-qe.hcpapps.net/get "HTTP/1.1 500 Internal Server Error"
---------------------------- Captured log teardown -----------------------------
09:53:47 +0000 INFO:backoff:Backing off _wait_dnsrecord_deleted(...) for 0.4s ([<testsuite.kuadrant.policy.dns.DNSRecord object at 0x7f71a74f59d0>])
09:53:47 +0000 INFO:backoff:Backing off _wait_dnsrecord_deleted(...) for 0.5s ([<testsuite.kuadrant.policy.dns.DNSRecord object at 0x7f71a7932cf0>])
09:53:48 +0000 INFO:backoff:Backing off _wait_dnsrecord_deleted(...) for 0.5s ([<testsuite.kuadrant.policy.dns.DNSRecord object at 0x7f71a751c800>])
09:53:49 +0000 INFO:backoff:Backing off _wait_dnsrecord_deleted(...) for 0.6s ([<testsuite.kuadrant.policy.dns.DNSRecord object at 0x7f71a751db20>])
09:53:49 +0000 INFO:backoff:Backing off _wait_dnsrecord_deleted(...) for 3.8s ([<testsuite.kuadrant.policy.dns.DNSRecord object at 0x7f71a751c230>])
__________________ test_limit[2 requests every 15 sec-route] ___________________
[gw1] linux -- Python 3.12.3 /home/runner/.cache/pypoetry/virtualenvs/kuadrant-testsuite-6EPd9kcO-py3.12/bin/python
testsuite/tests/singlecluster/limitador/test_basic_limit.py:37: in test_limit
    responses.assert_all(status_code=200)
testsuite/httpx/__init__.py:108: in assert_all
    assert request.status_code == status_code, (
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
E   AssertionError: Status code assertion failed for request 1 out of 2 requests: Result[status_code=500] != 200
------------------------------ Captured log call -------------------------------
09:53:34 +0000 INFO:httpx:HTTP Request: GET http://172.18.255.209/get "HTTP/1.1 500 Internal Server Error"
09:53:34 +0000 INFO:httpx:HTTP Request: GET http://172.18.255.209/get "HTTP/1.1 500 Internal Server Error"
------------------------------ Captured log call -------------------------------
09:53:55 +0000 INFO:httpx:HTTP Request: GET http://172.18.255.209/get "HTTP/1.1 500 Internal Server Error"
09:53:55 +0000 INFO:httpx:HTTP Request: GET http://172.18.255.209/get "HTTP/1.1 500 Internal Server Error"
------------------------------ Captured log call -------------------------------
09:54:15 +0000 INFO:httpx:HTTP Request: GET http://172.18.255.209/get "HTTP/1.1 500 Internal Server Error"
09:54:15 +0000 INFO:httpx:HTTP Request: GET http://172.18.255.209/get "HTTP/1.1 500 Internal Server Error"
------------------------------ Captured log call -------------------------------
09:54:35 +0000 INFO:httpx:HTTP Request: GET http://172.18.255.209/get "HTTP/1.1 500 Internal Server Error"
09:54:35 +0000 INFO:httpx:HTTP Request: GET http://172.18.255.209/get "HTTP/1.1 500 Internal Server Error"
_________________ test_limit[2 requests every 15 sec-gateway] __________________
[gw1] linux -- Python 3.12.3 /home/runner/.cache/pypoetry/virtualenvs/kuadrant-testsuite-6EPd9kcO-py3.12/bin/python
testsuite/tests/singlecluster/limitador/test_basic_limit.py:38: in test_limit
    assert client.get("/get").status_code == 429
E   AssertionError: assert 200 == 429
E    +  where 200 = <testsuite.httpx.Result object at 0x7fca8fbf7f20>.status_code
E    +    where <testsuite.httpx.Result object at 0x7fca8fbf7f20> = get('/get')
E    +      where get = <testsuite.httpx.ForceSNIClient object at 0x7fca8ff85d00>.get
------------------------------ Captured log call -------------------------------
09:54:46 +0000 INFO:backoff:Backing off request(...) for 1.0s (Result[error=timed out])
09:54:52 +0000 INFO:backoff:Backing off request(...) for 1.0s (Result[error=timed out])
09:54:58 +0000 INFO:backoff:Backing off request(...) for 2.0s (Result[error=timed out])
09:55:05 +0000 INFO:backoff:Backing off request(...) for 3.0s (Result[error=timed out])
09:55:10 +0000 INFO:httpx:HTTP Request: GET http://172.18.255.209/get "HTTP/1.1 200 OK"
09:55:10 +0000 INFO:httpx:HTTP Request: GET http://172.18.255.209/get "HTTP/1.1 200 OK"
09:55:11 +0000 INFO:httpx:HTTP Request: GET http://172.18.255.209/get "HTTP/1.1 200 OK"
------------------------------ Captured log call -------------------------------
09:55:32 +0000 INFO:httpx:HTTP Request: GET http://172.18.255.209/get "HTTP/1.1 200 OK"
09:55:33 +0000 INFO:httpx:HTTP Request: GET http://172.18.255.209/get "HTTP/1.1 200 OK"
09:55:33 +0000 INFO:httpx:HTTP Request: GET http://172.18.255.209/get "HTTP/1.1 200 OK"
------------------------------ Captured log call -------------------------------
09:55:54 +0000 INFO:httpx:HTTP Request: GET http://172.18.255.209/get "HTTP/1.1 200 OK"
09:55:54 +0000 INFO:httpx:HTTP Request: GET http://172.18.255.209/get "HTTP/1.1 200 OK"
09:55:54 +0000 INFO:httpx:HTTP Request: GET http://172.18.255.209/get "HTTP/1.1 200 OK"
------------------------------ Captured log call -------------------------------
09:56:15 +0000 INFO:httpx:HTTP Request: GET http://172.18.255.209/get "HTTP/1.1 200 OK"
09:56:15 +0000 INFO:httpx:HTTP Request: GET http://172.18.255.209/get "HTTP/1.1 200 OK"
09:56:15 +0000 INFO:httpx:HTTP Request: GET http://172.18.255.209/get "HTTP/1.1 200 OK"
=========================== short test summary info ============================
FAILED testsuite/tests/singlecluster/authorino/identity/api_key/test_auth_credentials.py::test_custom_selector[authorizationHeader] - assert 500 == 200
 +  where 500 = <testsuite.httpx.Result object at 0x7fef10902270>.status_code
FAILED testsuite/tests/singlecluster/gateway/test_basic.py::test_gateway_basic_dns_tls - assert 500 == 200
 +  where 500 = <testsuite.httpx.Result object at 0x7f71a9096b70>.status_code
FAILED testsuite/tests/singlecluster/limitador/test_basic_limit.py::test_limit[2 requests every 15 sec-route] - AssertionError: Status code assertion failed for request 1 out of 2 requests: Result[status_code=500] != 200
FAILED testsuite/tests/singlecluster/limitador/test_basic_limit.py::test_limit[2 requests every 15 sec-gateway] - AssertionError: assert 200 == 429
 +  where 200 = <testsuite.httpx.Result object at 0x7fca8fbf7f20>.status_code
 +    where <testsuite.httpx.Result object at 0x7fca8fbf7f20> = get('/get')
 +      where get = <testsuite.httpx.ForceSNIClient object at 0x7fca8ff85d00>.get
============== 4 failed, 1 passed, 12 rerun in 222.67s (0:03:42) ===============
make: *** [Makefile:36: smoke] Error 1

@azgabur
Copy link
Copy Markdown
Member Author

azgabur commented May 29, 2026

^ Not sure what is happening here but smoke passes locally

@azgabur azgabur requested review from averevki and crstrn13 May 29, 2026 10:02
Copy link
Copy Markdown
Contributor

@crstrn13 crstrn13 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! :shipit:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants